﻿using NUnit.Framework;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Searching;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Tests.Unit.Searching
{
    [TestFixture]
    public class SearcherGeneratorFacadeTest
    {
        private SearcherGeneratorFacade testee;


        public TestContext TestContext { get; set; }


        [SetUp]
        public void SetUp()
        {
            this.testee = new SearcherGeneratorFacade();
        }

        [Test]
        public void TestGetInstance()
        {
            Assert.AreEqual(typeof(CategorySearcherGenerator), CallGetInstance("category").GetType());
            Assert.AreEqual(typeof(CategorySearcherGenerator), CallGetInstance("c").GetType());
            Assert.AreEqual(typeof(CheckIdSearcherGenerator), CallGetInstance("id").GetType());
            Assert.AreEqual(typeof(FileNameSearcherGenerator), CallGetInstance("file").GetType());
            Assert.AreEqual(typeof(FileNameSearcherGenerator), CallGetInstance("f").GetType());
            Assert.AreEqual(typeof(KindSearcherGenerator), CallGetInstance("kind").GetType());
            Assert.AreEqual(typeof(KindSearcherGenerator), CallGetInstance("k").GetType());
            Assert.AreEqual(typeof(MesseageSearcherGenerator), CallGetInstance("message").GetType());
            Assert.AreEqual(typeof(MesseageSearcherGenerator), CallGetInstance("m").GetType());
            Assert.AreEqual(typeof(ProjectNameSearcherGenerator), CallGetInstance("project").GetType());
            Assert.AreEqual(typeof(ProjectNameSearcherGenerator), CallGetInstance("p").GetType());
        }

        [Test]
        public void TestSplitWordWithNull()
        {
            var actual = CallSplitWord(null);
            Assert.AreEqual("", actual.Item1);
            Assert.AreEqual("", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithEmpty()
        {
            var actual = CallSplitWord("");
            Assert.AreEqual("", actual.Item1);
            Assert.AreEqual("", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithWhiteSpace()
        {
            var actual = CallSplitWord("    ");
            Assert.AreEqual("", actual.Item1);
            Assert.AreEqual("    ", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithWordDoesNotHaveColon()
        {
            var actual = CallSplitWord("foo");
            Assert.AreEqual("", actual.Item1);
            Assert.AreEqual("foo", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithWordBeginsColon()
        {
            var actual = CallSplitWord(":foo");
            Assert.AreEqual("", actual.Item1);
            Assert.AreEqual("foo", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithWordHasColon()
        {
            var actual = CallSplitWord("foo:bar");
            Assert.AreEqual("foo", actual.Item1);
            Assert.AreEqual("bar", actual.Item2);
        }

        [Test]
        public void TestSplitWordWithWordHasMultiColons()
        {
            var actual = CallSplitWord("foo:bar:hoge");
            Assert.AreEqual("foo", actual.Item1);
            Assert.AreEqual("bar:hoge", actual.Item2);
        }

        private ISearcherGenerator CallGetInstance(string keyword)
        {
            MethodInfo method = this.testee.GetType().GetMethod("GetInstance", BindingFlags.Instance | BindingFlags.NonPublic);
            return (ISearcherGenerator)method.Invoke(this.testee, new object[] { keyword });
        }

        private Tuple<string, string> CallSplitWord(string word)
        {
            MethodInfo method = this.testee.GetType().GetMethod("SplitWord", BindingFlags.Instance | BindingFlags.NonPublic);
            return (Tuple<string, string>)method.Invoke(this.testee, new object[] { word });
        }
    }
}
